<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Running on Backends &mdash; pytket-manual  documentation</title>
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
      <link rel="stylesheet" href="_static/jupyter-sphinx.css" type="text/css" />
      <link rel="stylesheet" href="_static/thebelab.css" type="text/css" />
  <!--[if lt IE 9]>
    <script src="_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
        <script src="_static/jquery.js"></script>
        <script src="_static/underscore.js"></script>
        <script src="_static/doctools.js"></script>
        <script src="_static/thebelab-helper.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
        <script src="https://unpkg.com/@jupyter-widgets/html-manager@^0.20.0/dist/embed-amd.js"></script>
        <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
    <script src="_static/js/theme.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Compilation" href="manual_compiler.html" />
    <link rel="prev" title="Circuit Construction" href="manual_circuit.html" /> 
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
            <a href="index.html" class="icon icon-home"> pytket-manual
          </a>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="manual_intro.html">What is tket?</a></li>
<li class="toctree-l1"><a class="reference internal" href="manual_circuit.html">Circuit Construction</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Running on Backends</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#backend-requirements">Backend Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="#shots-and-sampling">Shots and Sampling</a></li>
<li class="toctree-l2"><a class="reference internal" href="#statevectors-and-unitaries">Statevectors and Unitaries</a></li>
<li class="toctree-l2"><a class="reference internal" href="#interpreting-results">Interpreting Results</a></li>
<li class="toctree-l2"><a class="reference internal" href="#expectation-value-calculations">Expectation Value Calculations</a></li>
<li class="toctree-l2"><a class="reference internal" href="#guidance-for-writing-hardware-agnostic-code">Guidance for Writing Hardware-Agnostic Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="#batch-submission">Batch Submission</a></li>
<li class="toctree-l2"><a class="reference internal" href="#embedding-into-qiskit">Embedding into Qiskit</a></li>
<li class="toctree-l2"><a class="reference internal" href="#advanced-topics">Advanced Topics</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#simulator-support-for-expectation-values">Simulator Support for Expectation Values</a></li>
<li class="toctree-l3"><a class="reference internal" href="#asynchronous-job-submission">Asynchronous Job Submission</a></li>
<li class="toctree-l3"><a class="reference internal" href="#persistent-handles">Persistent Handles</a></li>
<li class="toctree-l3"><a class="reference internal" href="#result-serialization">Result Serialization</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="manual_compiler.html">Compilation</a></li>
<li class="toctree-l1"><a class="reference internal" href="manual_noise.html">Noise and the Quantum Circuit Model</a></li>
<li class="toctree-l1"><a class="reference internal" href="manual_assertion.html">Assertion</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">More documentation:</span></p>
<ul>
<li class="toctree-l1"><a class="reference external" href="https://cqcl.github.io/tket/pytket/api/index.html">pytket</a></li>
</ul>

        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="index.html">pytket-manual</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
      <li>Running on Backends</li>
      <li class="wy-breadcrumbs-aside">
            <a href="_sources/manual_backend.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <div class="section" id="running-on-backends">
<h1>Running on Backends<a class="headerlink" href="#running-on-backends" title="Permalink to this headline"></a></h1>
<p>The interaction model for quantum computing in the near future is set to follow the co-processor model: there is a main program running on the classical host computer which routinely sends off jobs to a specialist device that can handle that class of computation efficiently, similar to interacting with GPUs and cloud HPC resources. We have already seen how to use <code class="docutils literal notranslate"><span class="pre">pytket</span></code> to describe a job to be performed with the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> class; the next step is to look at how we interact with the co-processor to run it.</p>
<p>A <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> represents a connection to some co-processor instance, which can be either quantum hardware or a simulator. It presents a uniform interface for submitting <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s to be processed and retrieving the results, allowing the general workflow of “generate, compile, process, retrieve, interpret” to be performed with little dependence on the specific co-processor used. This is to promote the development of platform-independent software, helping the code that you write to be more future-proof and encouraging exploration of the ever-changing landscape of quantum hardware solutions.</p>
<p>With the wide variety of <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s available, they naturally have very different capabilities and limitations. The class is designed to open up this information so that it is easy to examine at runtime and make hardware-dependent choices as needed for maximum performance, whilst providing a basic abstract model that is easy for proof-of-concept testing.</p>
<p>No <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s are currently provided with the core <code class="docutils literal notranslate"><span class="pre">pytket</span></code> package, but most extension modules will add simulators or devices from the given provider, such as the <code class="xref py py-class docutils literal notranslate"><span class="pre">AerBackend</span></code> and <code class="xref py py-class docutils literal notranslate"><span class="pre">IBMQBackend</span></code> with <code class="docutils literal notranslate"><span class="pre">pytket-qiskit</span></code> or the <code class="xref py py-class docutils literal notranslate"><span class="pre">HoneywellBackend</span></code> with <code class="docutils literal notranslate"><span class="pre">pytket-honeywell</span></code>.</p>
<div class="section" id="backend-requirements">
<h2>Backend Requirements<a class="headerlink" href="#backend-requirements" title="Permalink to this headline"></a></h2>
<p>Every device and simulator will have some restrictions to allow for a simpler implementation or because of the limits of engineering or noise within a device. For example, devices and simulators are typically designed to only support a small (but universal) gate set, so a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> containing other gate types could not be run immediately. However, as long as the fragment supported is universal, it is enough to be able to compile down to a semantically-equivalent <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> which satisfies the requirements, for example, by translating each unknown gate into sequences of known gates.</p>
<p>Other common restrictions presented by QPUs include the number of available qubits and their connectivity (multi-qubit gates may only be performed between adjacent qubits on the architecture). Measurements may also be noisy or take a long time on some QPUs, leading to the destruction or decoherence of any remaining quantum state, so they are artificially restricted to only happen in a single layer at the end of execution and mid-circuit measurements are rejected. More extremely, some classes of classical simulators will reject measurements entirely as they are designed to simulate pure quantum circuits (for example, when looking to yield a statevector or unitary deterministically).</p>
<p>Each <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> object is aware of the restrictions of the underlying device or simulator, encoding them as a collection of <code class="xref py py-class docutils literal notranslate"><span class="pre">Predicate</span></code> s. Each <code class="xref py py-class docutils literal notranslate"><span class="pre">Predicate</span></code> is essentially a Boolean property of a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> which must return <code class="docutils literal notranslate"><span class="pre">True</span></code> for the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> to successfully run. The set of <code class="xref py py-class docutils literal notranslate"><span class="pre">Predicate</span></code> s required by a <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> can be queried with <code class="xref py py-attr docutils literal notranslate"><span class="pre">Backend.required_predicates</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">IBMQBackend</span><span class="p">,</span> <span class="n">AerStateBackend</span>
<span class="n">dev_b</span> <span class="o">=</span> <span class="n">IBMQBackend</span><span class="p">(</span><span class="s2">&quot;ibmq_quito&quot;</span><span class="p">)</span>
<span class="n">sim_b</span> <span class="o">=</span> <span class="n">AerStateBackend</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">dev_b</span><span class="o">.</span><span class="n">required_predicates</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sim_b</span><span class="o">.</span><span class="n">required_predicates</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[NoClassicalControlPredicate, NoFastFeedforwardPredicate, NoMidMeasurePredicate, NoSymbolsPredicate, GateSetPredicate:{ U1 noop U2 CX Barrier Measure U3 }, DirectednessPredicate:{ Nodes: 5, Edges: 8 }]
[NoClassicalControlPredicate, NoFastFeedforwardPredicate, GateSetPredicate:{ CU1 CZ CX Unitary2qBox Sdg U1 Unitary1qBox SWAP S U2 CCX Y U3 Z X T noop Tdg Reset H }]
</pre></div>
</div>
</div>
</div>
<p>Knowing the requirements of each <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> is handy in case it has consequences for how you design a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>, but can generally be abstracted away. Calling <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.valid_circuit()</span></code> can check whether or not a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> satisfies every requirement to run on the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>, and if it is not immediately valid then <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.compile_circuit()</span></code> will modify the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> in-place to try to solve all of the remaining constraints when possible (note that restrictions on measurements or conditional gate support may not be fixed by compilation). To get a copy of the compiled circuit without modifying it in place, use <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_compiled_circuit()</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>

<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Ry</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CRz</span><span class="p">(</span><span class="o">-</span><span class="mf">0.6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>

<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">backend</span><span class="o">.</span><span class="n">valid_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">):</span>
    <span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
    <span class="k">assert</span> <span class="n">backend</span><span class="o">.</span><span class="n">valid_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">circ</span><span class="o">.</span><span class="n">get_commands</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[tk1(3.7, 0.3, 0) q[0];, tk1(0.5, 0.5, 3.5) q[1];, CX q[1], q[0];, tk1(0, 0, 0.3) q[0];, CX q[1], q[0];, Measure q[0] --&gt; c[0];, Measure q[1] --&gt; c[1];]
</pre></div>
</div>
</div>
</div>
<p>Now that we can prepare our <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s to be suitable for a given <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>, we can send them off to be run and examine the results. This is always done by calling <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuit()</span></code> which sends a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> for execution and returns a <code class="xref py py-class docutils literal notranslate"><span class="pre">ResultHandle</span></code> as an identifier for the job which can later be used to retrieve the actual results once the job has finished.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerStateBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Ry</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CRz</span><span class="p">(</span><span class="o">-</span><span class="mf">0.6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerStateBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
</div>
</div>
<p>The exact arguments to <code class="xref py py-meth docutils literal notranslate"><span class="pre">process_circuit()</span></code> and the means of retrieving results back are dependent on the type of data the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> can produce and whether it samples measurements or calculates the internal state of the quantum system.</p>
</div>
<div class="section" id="shots-and-sampling">
<h2>Shots and Sampling<a class="headerlink" href="#shots-and-sampling" title="Permalink to this headline"></a></h2>
<p>Running a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> on a quantum computer invovles applying the instructions to some quantum system to modify its state. Whilst we know that this state will form a vector (or linear map) in some Hilbert space, we cannot directly inspect it and obtain a complex vector/matrix to return to the classical host process. The best we can achieve is performing measurements to collapse the state and obtain a bit of information in the process. Since the measurements are not deterministic, each run of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> samples from some distribution. By obtaining many <em>shots</em> (the classical readout from each full run of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> from the initial state), we can start to predict what the underlying measurement distrubution looks like.</p>
<p>The interaction with a QPU (or a simulator that tries to imitate a device by sampling from the underlying complex statevector) is focused around requesting shots for a given <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>. The number of shots required is passed to <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuit()</span></code>. The result is retrieved using <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_result()</span></code>; and the shots are then given as a table from <code class="xref py py-meth docutils literal notranslate"><span class="pre">BackendResult.get_shots()</span></code>: each row of the table describes a shot in the order of execution, and the columns are the classical bits from the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
<span class="n">shots</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_shots</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">shots</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[[1 1]
 [0 1]
 [1 1]
 [0 1]
 [0 1]
 [1 1]
 [0 1]
 [0 1]
 [0 1]
 [1 1]
 [0 1]
 [1 1]
 [0 1]
 [1 1]
 [1 1]
 [0 1]
 [0 1]
 [1 1]
 [0 1]
 [1 1]]
</pre></div>
</div>
</div>
</div>
<p>For most applications, we are interested in the probability of each measurement outcome, so we need many shots for each experiment for high precision (it is quite typical to ask for several thousand or more). Even if we expect a single sharp peak in the distribution, as is the case from many of the popular textbook quantum algorithms (Deutsch-Jozsa, Bernstein-Vazirani, Shor, etc.), we will generally want to take many shots to help account for noise.</p>
<p>If we don’t care about the temporal order of the shots, we can instead retrieve a compact summary of the frequencies of observed results. The dictionary returned by <code class="xref py py-meth docutils literal notranslate"><span class="pre">BackendResult.get_counts()</span></code> maps tuples of bits to the number of shots that gave that result (keys only exist in the dictionary if this is non-zero). If probabilities are preferred to frequencies, we can apply the utility method <code class="xref py py-meth docutils literal notranslate"><span class="pre">probs_from_counts()</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">probs_from_counts</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">probs_from_counts</span><span class="p">(</span><span class="n">counts</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Counter({(1, 1): 1051, (0, 1): 949})
{(0, 1): 0.4745, (1, 1): 0.5255}
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><cite>Backend.process_circuit</cite> returns a handle to the computation to perform the quantum computation asynchronously. Non-blocking operations are essential when running circuits on remote devices, as submission and queuing times can be long. The handle may then be used to retrieve the results with <cite>Backend.get_result</cite>. If asynchronous computation is not needed, for example when running on a local simulator, pytket provides the shortcut <cite>Backend.run_circuit</cite> that will immediately execute the circuit and return a <cite>BackendResult</cite>.</p>
</div>
</div>
<div class="section" id="statevectors-and-unitaries">
<h2>Statevectors and Unitaries<a class="headerlink" href="#statevectors-and-unitaries" title="Permalink to this headline"></a></h2>
<p>Any form of sampling from a distribution will introduce sampling error and (unless it is a seeded simulator) non-deterministic results, whereas we could get much better accuracy and repeatability if we have the exact state of the underlying physical quantum system. Some simulators will provide direct access to this. The <code class="xref py py-meth docutils literal notranslate"><span class="pre">BackendResult.get_state()</span></code> method will give the full representation of the physical state as a vector in the <span class="math notranslate nohighlight">\(2^n\)</span>-dimensional Hilbert space, whenever the underlying simulator provides this.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerStateBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerStateBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="n">state</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">run_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span><span class="o">.</span><span class="n">get_state</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[0.     +0.j      0.70711-0.j      0.     +0.j      0.     +0.j
 0.     +0.j      0.     +0.j      0.     +0.j      0.     +0.70711j]
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>We have rounded the results here because simulators typically introduce a small amount of floating-point error, so killing near-zero entries gives a much more readable representation.</p>
</div>
<p>The majority of <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s will run the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> on the initial state <span class="math notranslate nohighlight">\(|0\rangle^{\otimes n}\)</span>. However, because we can form the composition of <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s, we want to be able to test them with open inputs. When the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> is purely quantum, we can represent its effect as an open circuit by a unitary matrix acting on the <span class="math notranslate nohighlight">\(2^n\)</span>-dimensional Hilbert space. The <code class="xref py py-class docutils literal notranslate"><span class="pre">AerUnitaryBackend</span></code> from <code class="docutils literal notranslate"><span class="pre">pytket-qiskit</span></code> is designed exactly for this.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerUnitaryBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerUnitaryBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="n">unitary</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">run_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span><span class="o">.</span><span class="n">get_unitary</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">unitary</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[[ 0.70711+0.j  0.     +0.j  0.70711-0.j  0.     +0.j]
 [ 0.     +0.j  0.70711+0.j  0.     +0.j  0.70711-0.j]
 [ 0.     +0.j  0.70711-0.j  0.     +0.j -0.70711+0.j]
 [ 0.70711-0.j  0.     +0.j -0.70711+0.j  0.     +0.j]]
</pre></div>
</div>
</div>
</div>
<p>Whilst the drive for quantum hardware is driven by the limited scalability of simulators, using statevector and unitary simulators will see long-term practical use to obtain high-precision results as well as for verifying the correctness of circuit designs. For the latter, we can assert that they match some expected reference state, but simply comparing the vectors/matrices may be too strict a test given that they could differ by a global phase but still be operationally equivalent. The utility methods <code class="xref py py-meth docutils literal notranslate"><span class="pre">compare_statevectors()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">compare_unitaries()</span></code> will compare two vectors/matrices for approximate equivalence accounting for global phase.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket.utils.results</span> <span class="kn">import</span> <span class="n">compare_statevectors</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="n">ref_state</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mf">2.</span><span class="p">)</span>      <span class="c1"># |+0&gt;</span>
<span class="n">gph_state</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span> <span class="o">*</span> <span class="mi">1</span><span class="n">j</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mf">2.</span><span class="p">)</span> <span class="c1"># i|+0&gt;</span>
<span class="n">prm_state</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mf">2.</span><span class="p">)</span>      <span class="c1"># |0+&gt;</span>

<span class="nb">print</span><span class="p">(</span><span class="n">compare_statevectors</span><span class="p">(</span><span class="n">ref_state</span><span class="p">,</span> <span class="n">gph_state</span><span class="p">))</span>   <span class="c1"># Differ by global phase</span>
<span class="nb">print</span><span class="p">(</span><span class="n">compare_statevectors</span><span class="p">(</span><span class="n">ref_state</span><span class="p">,</span> <span class="n">prm_state</span><span class="p">))</span>   <span class="c1"># Differ by qubit permutation</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>True
False
</pre></div>
</div>
</div>
</div>
<p>Be warned that simulating any <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> that interacts with classical data (e.g. conditional gates and measurements) or deliberately collapses the quantum state (e.g. <code class="docutils literal notranslate"><span class="pre">OpType.Collapse</span></code> and <code class="docutils literal notranslate"><span class="pre">OpType.Reset</span></code>) would not yield a deterministic result in the system’s Hilbert space, so these will be rejected by the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>.</p>
</div>
<div class="section" id="interpreting-results">
<h2>Interpreting Results<a class="headerlink" href="#interpreting-results" title="Permalink to this headline"></a></h2>
<p>Once we have obtained these results, we still have the matter of understanding what they mean. This corresponds to asking “which (qu)bit is which in this data structure?”</p>
<p>By default, the bits in readouts (shots and counts) are ordered in Increasing Lexicographical Order (ILO) with respect to their <code class="xref py py-class docutils literal notranslate"><span class="pre">UnitID</span></code> s. That is, the register <code class="docutils literal notranslate"><span class="pre">c</span></code> will be listed completely before any bits in register <code class="docutils literal notranslate"><span class="pre">d</span></code>, and within each register the indices are given in increasing order. Many quantum software platforms including Qiskit and pyQuil will natively use the reverse order (Decreasing Lexicographical Order - DLO), so users familiar with them may wish to request that the order is changed when retrieving results.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket.circuit</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">BasisOrder</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>     <span class="c1"># write 0 to c[0] and 1 to c[1]</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_counts</span><span class="p">())</span>   <span class="c1"># ILO gives (c[0], c[1]) == (0, 1)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_counts</span><span class="p">(</span><span class="n">basis</span><span class="o">=</span><span class="n">BasisOrder</span><span class="o">.</span><span class="n">dlo</span><span class="p">))</span>
                                    <span class="c1"># DLO gives (c[1], c[0]) == (1, 0)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Counter({(0, 1): 10})
Counter({(1, 0): 10})
</pre></div>
</div>
</div>
</div>
<p>The choice of ILO or DLO defines the ordering of a bit sequence, but this can still be interpreted into the index of a statevector in two ways: by mapping the bits to a big-endian (BE) or little-endian (LE) integer. Every statevector and unitary in <code class="docutils literal notranslate"><span class="pre">pytket</span></code> uses a BE encoding (if LE is preferred, note that the ILO-LE interpretation gives the same result as DLO-BE for statevectors and unitaries, so just change the <code class="docutils literal notranslate"><span class="pre">basis</span></code> argument accordingly). The ILO-BE convention gives unitaries of individual gates as they typically appear in common textbooks <a class="reference internal" href="#niel2001" id="id1"><span>[Niel2001]</span></a>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket.circuit</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">BasisOrder</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerUnitaryBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerUnitaryBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_unitary</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_unitary</span><span class="p">(</span><span class="n">basis</span><span class="o">=</span><span class="n">BasisOrder</span><span class="o">.</span><span class="n">dlo</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]]
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]]
</pre></div>
</div>
</div>
</div>
<p>Suppose that we only care about a subset of the measurements used in a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>. A shot table is a <code class="docutils literal notranslate"><span class="pre">numpy.ndarray</span></code>, so it can be filtered by column selections. To identify which columns need to be retained/removed, we are able to predict their column indices from the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> object. <code class="xref py py-attr docutils literal notranslate"><span class="pre">Circuit.bit_readout</span></code> maps <code class="xref py py-class docutils literal notranslate"><span class="pre">Bit</span></code> s to their column index (assuming the ILO convention).</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">Bit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">expectation_from_shots</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CZ</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>   <span class="c1"># Generate the state we want to consider</span>

<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>                           <span class="c1"># Measure ZXY operator qubit-wise</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>

<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="mi">2000</span><span class="p">)</span>
<span class="n">shots</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_shots</span><span class="p">()</span>

<span class="c1"># To extract the expectation value for ZIY, we only want to consider bits c[0] and c[2]</span>
<span class="n">bitmap</span> <span class="o">=</span> <span class="n">circ</span><span class="o">.</span><span class="n">bit_readout</span>
<span class="n">shots</span> <span class="o">=</span> <span class="n">shots</span><span class="p">[:,</span> <span class="p">[</span><span class="n">bitmap</span><span class="p">[</span><span class="n">Bit</span><span class="p">(</span><span class="mi">0</span><span class="p">)],</span> <span class="n">bitmap</span><span class="p">[</span><span class="n">Bit</span><span class="p">(</span><span class="mi">2</span><span class="p">)]]]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">expectation_from_shots</span><span class="p">(</span><span class="n">shots</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>0.014000000000000012
</pre></div>
</div>
</div>
</div>
<p>If measurements occur at the end of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>, then we can associate each measurement to the qubit that was measured. <code class="xref py py-attr docutils literal notranslate"><span class="pre">Circuit.qubit_readout</span></code> gives the equivalent map to column indices for <code class="xref py py-class docutils literal notranslate"><span class="pre">Qubit</span></code> s, and <code class="xref py py-attr docutils literal notranslate"><span class="pre">Circuit.qubit_to_bit_map</span></code> relates each measured <code class="xref py py-class docutils literal notranslate"><span class="pre">Qubit</span></code> to the <code class="xref py py-class docutils literal notranslate"><span class="pre">Bit</span></code> that holds the corresponding measurement result.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">Qubit</span><span class="p">,</span> <span class="n">Bit</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CZ</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Measure</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Measure</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">circ</span><span class="o">.</span><span class="n">bit_readout</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">circ</span><span class="o">.</span><span class="n">qubit_readout</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">circ</span><span class="o">.</span><span class="n">qubit_to_bit_map</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>{c[0]: 0, c[1]: 1}
{q[0]: 0, q[2]: 1}
{q[0]: c[0], q[2]: c[1]}
</pre></div>
</div>
</div>
</div>
<p>For more control over the bits extracted from the results, we can instead call <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_result()</span></code>. The <code class="xref py py-class docutils literal notranslate"><span class="pre">BackendResult</span></code> object returned wraps up all the information returned from the experiment and allows it to be projected into any preferred way of viewing it. In particular, we can provide the list of <code class="xref py py-class docutils literal notranslate"><span class="pre">Bit</span></code> s we want to look at in the shot table/counts dictionary, and given the exact permutation we want (and similarly for the permutation of <code class="xref py py-class docutils literal notranslate"><span class="pre">Qubit</span></code> s for statevectors/unitaries).</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">Bit</span><span class="p">,</span> <span class="n">Qubit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span><span class="p">,</span> <span class="n">AerStateBackend</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Ry</span><span class="p">(</span><span class="o">-</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">state_b</span> <span class="o">=</span> <span class="n">AerStateBackend</span><span class="p">()</span>
<span class="n">state_b</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">state_b</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>

<span class="c1"># Make q[1] the most-significant qubit, so interesting state uses consecutive coefficients</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">state_b</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_state</span><span class="p">([</span><span class="n">Qubit</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">Qubit</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">Qubit</span><span class="p">(</span><span class="mi">2</span><span class="p">)]))</span>

<span class="n">circ</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">shot_b</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">shot_b</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">shot_b</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">shot_b</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>

<span class="c1"># Marginalise out q[0] from counts</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_counts</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get_counts</span><span class="p">([</span><span class="n">Bit</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">Bit</span><span class="p">(</span><span class="mi">2</span><span class="p">)]))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>[ 0.63003676+0.00000000e+00j -0.32101976+1.96567911e-17j
  0.63003676-3.85786248e-17j -0.32101976+3.93135823e-17j
  0.        +0.00000000e+00j  0.        +0.00000000e+00j
  0.        +0.00000000e+00j  0.        +0.00000000e+00j]
Counter({(0, 0, 0): 814, (1, 0, 0): 800, (0, 0, 1): 207, (1, 0, 1): 179})
Counter({(0, 0): 1614, (0, 1): 386})
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="expectation-value-calculations">
<h2>Expectation Value Calculations<a class="headerlink" href="#expectation-value-calculations" title="Permalink to this headline"></a></h2>
<p>One of the most common calculations performed with a quantum state <span class="math notranslate nohighlight">\(\left| \psi \right&gt;\)</span> is to obtain an expectation value <span class="math notranslate nohighlight">\(\langle \psi | H | \psi \rangle\)</span>. For many applications, the operator <span class="math notranslate nohighlight">\(H\)</span> can be expressed as a tensor product of Pauli matrices, or a linear combination of these. Given any (pure quantum) <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> and any <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>, the utility methods <code class="xref py py-meth docutils literal notranslate"><span class="pre">get_pauli_expectation_value()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">get_operator_expectation_value()</span></code> will generate the expectation value of the state under some operator using whatever results the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> supports. This includes adding measurements in the appropriate basis (if needed by the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>), running <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.compile_circuit()</span></code>, and obtaining and interpreting the results. For operators with many terms, it can optionally perform some basic measurement reduction techniques to cut down the number of <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s actually run by measuring multiple terms with simultaneous measurements in the same <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">Qubit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="kn">from</span> <span class="nn">pytket.partition</span> <span class="kn">import</span> <span class="n">PauliPartitionStrat</span>
<span class="kn">from</span> <span class="nn">pytket.pauli</span> <span class="kn">import</span> <span class="n">Pauli</span><span class="p">,</span> <span class="n">QubitPauliString</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">get_pauli_expectation_value</span><span class="p">,</span> <span class="n">get_operator_expectation_value</span>
<span class="kn">from</span> <span class="nn">pytket.utils.operators</span> <span class="kn">import</span> <span class="n">QubitPauliOperator</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CZ</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>   <span class="c1"># Generate the state we want to consider</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>

<span class="n">zxy</span> <span class="o">=</span> <span class="n">QubitPauliString</span><span class="p">({</span>
        <span class="n">Qubit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Z</span><span class="p">,</span>
        <span class="n">Qubit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">X</span><span class="p">,</span>
        <span class="n">Qubit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Y</span><span class="p">})</span>
<span class="n">xzi</span> <span class="o">=</span> <span class="n">QubitPauliString</span><span class="p">({</span>
        <span class="n">Qubit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">X</span><span class="p">,</span>
        <span class="n">Qubit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Z</span><span class="p">})</span>
<span class="n">op</span> <span class="o">=</span> <span class="n">QubitPauliOperator</span><span class="p">({</span>
        <span class="n">QubitPauliString</span><span class="p">()</span> <span class="p">:</span> <span class="mf">0.3</span><span class="p">,</span>
        <span class="n">zxy</span> <span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
        <span class="n">xzi</span> <span class="p">:</span> <span class="mi">1</span><span class="p">})</span>
<span class="nb">print</span><span class="p">(</span><span class="n">get_pauli_expectation_value</span><span class="p">(</span>
        <span class="n">circ</span><span class="p">,</span>
        <span class="n">zxy</span><span class="p">,</span>
        <span class="n">backend</span><span class="p">,</span>
        <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">get_operator_expectation_value</span><span class="p">(</span>
        <span class="n">circ</span><span class="p">,</span>
        <span class="n">op</span><span class="p">,</span>
        <span class="n">backend</span><span class="p">,</span>
        <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">,</span>
        <span class="n">partition_strat</span><span class="o">=</span><span class="n">PauliPartitionStrat</span><span class="o">.</span><span class="n">CommutingSets</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>0.02200000000000002
(0.2750000000000001+0j)
</pre></div>
</div>
</div>
</div>
<p>If you want a greater level of control over the procedure, then you may wish to write your own method for calculating <span class="math notranslate nohighlight">\(\langle \psi | H | \psi \rangle\)</span>. This is simple multiplication if we are given the statevector <span class="math notranslate nohighlight">\(| \psi \rangle\)</span>, but is slightly more complicated for measured systems. Since each measurement projects into either the subspace of +1 or -1 eigenvectors, we can assign +1 to each <code class="docutils literal notranslate"><span class="pre">0</span></code> readout and -1 to each <code class="docutils literal notranslate"><span class="pre">1</span></code> readout and take the average across all shots. When the desired operator is given by the product of multiple measurements, the contribution of +1 or -1 is dependent on the parity (XOR) of each measurement result in that shot. <code class="docutils literal notranslate"><span class="pre">pytket</span></code> provides some utility functions to wrap up this calculation and apply it to either a shot table (<code class="xref py py-meth docutils literal notranslate"><span class="pre">expectation_from_shots()</span></code>) or a counts dictionary (<code class="xref py py-meth docutils literal notranslate"><span class="pre">expectation_from_counts()</span></code>).</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">expectation_from_counts</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CZ</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>   <span class="c1"># Generate the state we want to consider</span>

<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>                           <span class="c1"># Want to measure expectation for Pauli ZXY</span>
<span class="n">circ</span><span class="o">.</span><span class="n">Rx</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>                     <span class="c1"># Measure ZII, IXI, IIY separately</span>
<span class="n">circ</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>

<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="mi">2000</span><span class="p">)</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">expectation_from_counts</span><span class="p">(</span><span class="n">counts</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Counter({(0, 0, 0): 430, (0, 1, 0): 404, (0, 0, 1): 387, (0, 1, 1): 386, (1, 0, 1): 102, (1, 0, 0): 98, (1, 1, 1): 97, (1, 1, 0): 96})
0.014000000000000012
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="xref py py-meth docutils literal notranslate"><span class="pre">expectation_from_shots()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">expectation_from_counts()</span></code> take into account every classical bit in the results object. If the expectation value of interest is a product of only a subset of the measurements in the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> (as is the case when simultaneously measuring several commuting operators), then you will want to filter/marginalise out the ignored bits when performing this calculation.</p>
</div>
</div>
<div class="section" id="guidance-for-writing-hardware-agnostic-code">
<h2>Guidance for Writing Hardware-Agnostic Code<a class="headerlink" href="#guidance-for-writing-hardware-agnostic-code" title="Permalink to this headline"></a></h2>
<p>Writing code for experiments that can be retargeted to different <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s can be a challenge, but has many great payoffs for long-term developments. Being able to experiment with new devices and simulators helps to identify which is best for the needs of the experiment and how this changes with the experiment parameters (such as size of chemical molecule being simulated, or choice of model to train for a neural network). Being able to react to changes in device availability helps get your results faster when contesting against queues for device access or downtime for maintenance, in addition to moving on if a device is retired from live service and taking advantage of the newest devices as soon as they come online. This is especially important in the near future as there is no clear frontrunner in terms of device, manufacturer, or even fundamental quantum technology, and the rate at which they are improving performance and scale is so high that it is essential to not get left behind with old systems.</p>
<p>One of the major counter-arguments against developing hardware-agnostic experiments is that the manual incorporation of the target architecture’s connectivity and noise characteristics into the circuit design and choice of error mitigation/detection/correction strategies obtains the optimal performance from the device. The truth is that hardware characteristics are highly variable over time, invalidating noise models after only a few hours <a class="reference internal" href="#wils2020" id="id2"><span>[Wils2020]</span></a> and requiring regular recalibration. Over the lifetime of the device, this could lead to some qubits or couplers becoming so ineffective that they are removed from the system by the providers, giving drastic changes to the connectivity and admissible circuit designs. The instability of the experiment designs is difficult to argue when the optimal performance on one of today’s devices is likely to be surpassed by an average performance on another device a short time after.</p>
<p>We have already seen that devices and simulators will have different sets of requirements on the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s they can accept and different types of results they can return, so hardware-agnosticism will not always come for free. The trick is to spot these differences and handle them on-the-fly at runtime. The design of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> class in <code class="docutils literal notranslate"><span class="pre">pytket</span></code> aims to expose the fundamental requirements that require consideration for circuit design, compilation, and result interpretation in such a way that they can easily be queried at runtime to dynamically adapt the experiment procedure. All other aspects of backend interaction that are shared between different <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s are then unified for ease of integration. In practice, the constraints of the algorithm might limit the choice of <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>, or we might choose to forego the ability to run on statevector simulators so that we only have to define the algorithm to calculate using counts, but we can still be agnostic within these categories.</p>
<p>The first point in an experiment where you might have to act differently between <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s is during <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> construction. A <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> may support a non-universal fragment of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> language, typically relating to their interaction with classical data – either full interaction, no mid-circuit measurement and conditional operations, or no measurement at all for statevector and unitary simulators. If the algorithm chosen requires mid-circuit measurement, then we must sacrifice some freedom of choice of <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> to accommodate this. For safety, it could be beneficial to include assertions that the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> provided meets the expectations of the algorithm.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span> <span class="c1">#, AerStateBackend</span>
<span class="kn">from</span> <span class="nn">pytket.predicates</span> <span class="kn">import</span> <span class="n">NoMidMeasurePredicate</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>      <span class="c1"># Choose backend in one place</span>
<span class="c1"># backend = AerStateBackend()   # A backend that is incompatible with the experiment</span>

<span class="c1"># For algorithms using mid-circuit measurement, we can assert this is valid</span>
<span class="n">qkd</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">qkd</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Measure</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>      <span class="c1"># Prepare a random bit in the Z basis</span>
<span class="n">qkd</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Measure</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Eavesdropper measures in the X basis</span>
<span class="n">qkd</span><span class="o">.</span><span class="n">Measure</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>           <span class="c1"># Recipient measures in the Z basis</span>

<span class="k">assert</span> <span class="n">backend</span><span class="o">.</span><span class="n">supports_counts</span>  <span class="c1"># Using AerStateBackend would fail at this check</span>
<span class="k">assert</span> <span class="n">NoMidMeasurePredicate</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">backend</span><span class="o">.</span><span class="n">required_predicates</span>
<span class="n">backend</span><span class="o">.</span><span class="n">compile_circuit</span><span class="p">(</span><span class="n">qkd</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">qkd</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Counter({(0, 0, 0): 141, (1, 0, 1): 130, (1, 1, 1): 128, (0, 0, 1): 127, (1, 1, 0): 126, (0, 1, 1): 120, (1, 0, 0): 117, (0, 1, 0): 111})
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The same effect can be achieved by <code class="docutils literal notranslate"><span class="pre">assert</span> <span class="pre">backend.valid_circuit(qkd)</span></code> after compilation. However, when designing the compilation procedure manually, it is unclear whether a failure for this assertion would come from the incompatibility of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> for the experiment or from the compilation failing.</p>
</div>
<p>Otherwise, a practical solution around different measurement requirements is to separate the design into “state circuits” and “measurement circuits”. At the point of running on the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>, we can then choose to either just send the state circuit for statevector calculations or compose it with the measurement circuits to run on sampling <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s.</p>
<p>At runtime, we can check whether a particular result type is supported using the <code class="xref py py-attr docutils literal notranslate"><span class="pre">Backend.supports_X</span></code> properties, whereas restrictions on the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s supported can be inspected with <code class="xref py py-attr docutils literal notranslate"><span class="pre">Backend.required_predicates</span></code>.</p>
<p>Whilst the demands of each <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> on the properties of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> necessitate different compilation procedures, using the default compilation sequences provided with <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.compile_circuit()</span></code> handles compiling generically.</p>
<p>Similarly, every <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> can use <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuit()</span></code> identically. Additional <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>-specific arguments (such as the number of shots required or the seed for a simulator) will just be ignored if passed to a <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> that does not use them.</p>
<p>For the final steps of retrieving and interpreting the results, it suffices to just case-split on the form of data we can retrieve again with <code class="xref py py-attr docutils literal notranslate"><span class="pre">Backend.supports_X</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span> <span class="c1">#, AerStateBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">expectation_from_counts</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>      <span class="c1"># Choose backend in one place</span>
<span class="c1"># backend = AerStateBackend()   # Alternative backend with different requirements and result type</span>

<span class="c1"># For many algorithms, we can separate the state preparation from measurements</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>           <span class="c1"># Apply e^{0.135 i pi XY} to the initial state</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">V</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">Rz</span><span class="p">(</span><span class="o">-</span><span class="mf">0.27</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">Vdg</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">measure</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>     <span class="c1"># Measure the YZ operator via YI and IZ</span>
<span class="n">measure</span><span class="o">.</span><span class="n">V</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>

<span class="k">if</span> <span class="n">backend</span><span class="o">.</span><span class="n">supports_counts</span><span class="p">:</span>
    <span class="n">circ</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">measure</span><span class="p">)</span>

<span class="n">circ</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_compiled_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>

<span class="n">expectation</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="n">backend</span><span class="o">.</span><span class="n">supports_state</span><span class="p">:</span>
    <span class="n">yz</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">([</span>
        <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="n">j</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">1</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]])</span>
    <span class="n">svec</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_state</span><span class="p">()</span>
    <span class="n">expectation</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">vdot</span><span class="p">(</span><span class="n">svec</span><span class="p">,</span> <span class="n">yz</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">svec</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
    <span class="n">expectation</span> <span class="o">=</span> <span class="n">expectation_from_counts</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">expectation</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>-0.010999999999999899
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="batch-submission">
<h2>Batch Submission<a class="headerlink" href="#batch-submission" title="Permalink to this headline"></a></h2>
<p>Current public-access quantum computers tend to implement either a queueing or a reservation system for mediating access. Whilst the queue-based access model gives relative fairness, guarantees availability, and maximises throughput and utilisation of the hardware, it also presents a big problem to the user with regards to latency. Whenever a circuit is submitted, not only must the user wait for it to be run on the hardware, but they must wait longer for their turn before it can even start running. This can end up dominating the time taken for the overall experiment, especially when demand is high for a particular device.</p>
<p>We can mitigate the problem of high queue latency by batching many <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s together. This means that we only have to wait the queue time once, since after the first <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> is run the next one is run immediately rather than joining the end of the queue.</p>
<p>To maximise the benefits of batch submission, it is advisable to generate as many of your <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s as possible at the same time to send them all off together. This is possible when, for example, generating every measurement circuit for an expectation value calculation, or sampling several parameter values from a local neighbourhood in a variational procedure. The method <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuits()</span></code> (plural) will then submit all the provided <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s simultaneously and return a <code class="xref py py-class docutils literal notranslate"><span class="pre">ResultHandle</span></code> for each <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> to allow each result to be extracted individually for interpretation. Since there is no longer a single <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> being handled from start to finish, it may be necessary to store additional data to record how to interpret them, like the set of <code class="xref py py-class docutils literal notranslate"><span class="pre">Bit</span></code> s to extract for each <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> or the coefficient to multiply the expectation value by.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">IBMQBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">expectation_from_counts</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">IBMQBackend</span><span class="p">(</span><span class="s2">&quot;ibmq_quito&quot;</span><span class="p">)</span>

<span class="n">state</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">state</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># Compute expectation value for -0.3i ZZZ + 0.8 XZZ + 1.2 XXX</span>
<span class="n">zzz</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">zzz</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">xzz</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">xzz</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">xxx</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">xxx</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">circ_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="p">[</span><span class="n">zzz</span><span class="p">,</span> <span class="n">xzz</span><span class="p">,</span> <span class="n">xxx</span><span class="p">]:</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
    <span class="n">c</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
    <span class="n">circ_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="n">coeff_list</span> <span class="o">=</span> <span class="p">[</span>
    <span class="o">-</span><span class="mf">0.3</span><span class="n">j</span><span class="p">,</span>  <span class="c1"># ZZZ</span>
    <span class="mf">0.8</span><span class="p">,</span>    <span class="c1"># XZZ</span>
    <span class="mf">1.2</span>     <span class="c1"># XXX</span>
<span class="p">]</span>
<span class="n">circ_list</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_compiled_circuits</span><span class="p">(</span><span class="n">circ_list</span><span class="p">)</span>

<span class="n">handle_list</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuits</span><span class="p">(</span><span class="n">circ_list</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>
<span class="n">result_list</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_results</span><span class="p">(</span><span class="n">handle_list</span><span class="p">)</span>

<span class="n">expectation</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">coeff</span><span class="p">,</span> <span class="n">result</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">coeff_list</span><span class="p">,</span> <span class="n">result_list</span><span class="p">):</span>
    <span class="n">counts</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
    <span class="n">expectation</span> <span class="o">+=</span> <span class="n">coeff</span> <span class="o">*</span> <span class="n">expectation_from_counts</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">expectation</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>(1.2047999999999999-0.0015000000000000013j)
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Currently, only the devices from IBMQ, Honeywell and Amazon Braket support a queue model and benefit from this methodology, though more may adopt this in future. The <code class="xref py py-class docutils literal notranslate"><span class="pre">AerBackend</span></code> simulator can take advantage of batch submission for parallelisation. In all other cases, <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuits()</span></code> will just loop through each <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> in turn.</p>
</div>
</div>
<div class="section" id="embedding-into-qiskit">
<h2>Embedding into Qiskit<a class="headerlink" href="#embedding-into-qiskit" title="Permalink to this headline"></a></h2>
<p>Not only is the goal of tket to be a device-agnostic platform, but also interface-agnostic, so users are not obliged to have to work entirely in tket to benefit from the wide range of devices supported. For example, Qiskit is currently the most widely adopted quantum software development platform, providing its own modules for building and compiling circuits, submitting to backends, applying error mitigation techniques and combining these into higher-level algorithms. Each <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> in <code class="docutils literal notranslate"><span class="pre">pytket</span></code> can be wrapped up to imitate a Qiskit backend, allowing the benefits of tket to be felt in existing Qiskit projects with minimal work.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">qiskit.utils</span> <span class="kn">import</span> <span class="n">QuantumInstance</span>
<span class="kn">from</span> <span class="nn">qiskit.algorithms</span> <span class="kn">import</span> <span class="n">Grover</span><span class="p">,</span> <span class="n">AmplificationProblem</span>
<span class="kn">from</span> <span class="nn">qiskit.circuit</span> <span class="kn">import</span> <span class="n">QuantumCircuit</span>

<span class="kn">from</span> <span class="nn">pytket.extensions.qulacs</span> <span class="kn">import</span> <span class="n">QulacsBackend</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit.tket_backend</span> <span class="kn">import</span> <span class="n">TketBackend</span>

<span class="n">b</span> <span class="o">=</span> <span class="n">QulacsBackend</span><span class="p">()</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">TketBackend</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">b</span><span class="o">.</span><span class="n">default_compilation_pass</span><span class="p">())</span>
<span class="n">qinstance</span> <span class="o">=</span> <span class="n">QuantumInstance</span><span class="p">(</span><span class="n">backend</span><span class="p">)</span>

<span class="n">oracle</span> <span class="o">=</span> <span class="n">QuantumCircuit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">oracle</span><span class="o">.</span><span class="n">cz</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">is_good_state</span><span class="p">(</span><span class="n">bitstr</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">sum</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">bitstr</span><span class="p">))</span> <span class="o">==</span> <span class="mi">2</span>

<span class="n">problem</span> <span class="o">=</span> <span class="n">AmplificationProblem</span><span class="p">(</span><span class="n">oracle</span><span class="o">=</span><span class="n">oracle</span><span class="p">,</span> <span class="n">is_good_state</span><span class="o">=</span><span class="n">is_good_state</span><span class="p">)</span>
<span class="n">grover</span> <span class="o">=</span> <span class="n">Grover</span><span class="p">(</span><span class="n">quantum_instance</span><span class="o">=</span><span class="n">qinstance</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">grover</span><span class="o">.</span><span class="n">amplify</span><span class="p">(</span><span class="n">problem</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Top measurement:&quot;</span><span class="p">,</span> <span class="n">result</span><span class="o">.</span><span class="n">top_measurement</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Top measurement: 11
</pre></div>
</div>
</div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Since Qiskit may not be able to solve all of the constraints of the chosen device/simulator, some compilation may be required after a circuit is passed to the <code class="xref py py-class docutils literal notranslate"><span class="pre">TketBackend</span></code>, or it may just be preferable to do so to take advantage of the sophisticated compilation solutions provided in <code class="docutils literal notranslate"><span class="pre">pytket</span></code>. Upon constructing the <code class="xref py py-class docutils literal notranslate"><span class="pre">TketBackend</span></code>, you can provide a <code class="docutils literal notranslate"><span class="pre">pytket</span></code> compilation pass to apply to each circuit, e.g. <code class="docutils literal notranslate"><span class="pre">TketBackend(backend,</span> <span class="pre">backend.default_compilation_pass())</span></code>. Some experimentation may be required to find a combination of <code class="docutils literal notranslate"><span class="pre">qiskit.transpiler.PassManager</span></code> and <code class="docutils literal notranslate"><span class="pre">pytket</span></code> compilation passes that executes successfully.</p>
</div>
</div>
<div class="section" id="advanced-topics">
<h2>Advanced Topics<a class="headerlink" href="#advanced-topics" title="Permalink to this headline"></a></h2>
<div class="section" id="simulator-support-for-expectation-values">
<h3>Simulator Support for Expectation Values<a class="headerlink" href="#simulator-support-for-expectation-values" title="Permalink to this headline"></a></h3>
<p>Some simulators will have dedicated support for fast expectation value calculations. In this special case, they will provide extra methods <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_pauli_expectation_value()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_operator_expectation_value()</span></code>, which take a <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> and some operator and directly return the expectation value. Again, we can check whether a <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> has this feature with <code class="xref py py-attr docutils literal notranslate"><span class="pre">Backend.supports_expectation</span></code>.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span><span class="p">,</span> <span class="n">Qubit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerStateBackend</span>
<span class="kn">from</span> <span class="nn">pytket.pauli</span> <span class="kn">import</span> <span class="n">Pauli</span><span class="p">,</span> <span class="n">QubitPauliString</span>
<span class="kn">from</span> <span class="nn">pytket.utils.operators</span> <span class="kn">import</span> <span class="n">QubitPauliOperator</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">AerStateBackend</span><span class="p">()</span>

<span class="n">state</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">state</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">V</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

<span class="n">xxy</span> <span class="o">=</span> <span class="n">QubitPauliString</span><span class="p">({</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">X</span><span class="p">,</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">X</span><span class="p">,</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Y</span><span class="p">})</span>
<span class="n">zzi</span> <span class="o">=</span> <span class="n">QubitPauliString</span><span class="p">({</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Z</span><span class="p">,</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Z</span><span class="p">})</span>
<span class="n">iiz</span> <span class="o">=</span> <span class="n">QubitPauliString</span><span class="p">({</span>
    <span class="n">Qubit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="p">:</span> <span class="n">Pauli</span><span class="o">.</span><span class="n">Z</span><span class="p">})</span>
<span class="n">op</span> <span class="o">=</span> <span class="n">QubitPauliOperator</span><span class="p">({</span>
    <span class="n">QubitPauliString</span><span class="p">()</span> <span class="p">:</span> <span class="o">-</span><span class="mf">0.5</span><span class="p">,</span>
    <span class="n">xxy</span> <span class="p">:</span> <span class="mf">0.7</span><span class="p">,</span>
    <span class="n">zzi</span> <span class="p">:</span> <span class="mf">1.4</span><span class="p">,</span>
    <span class="n">iiz</span> <span class="p">:</span> <span class="mf">3.2</span><span class="p">})</span>

<span class="k">assert</span> <span class="n">backend</span><span class="o">.</span><span class="n">supports_expectation</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_compiled_circuit</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">backend</span><span class="o">.</span><span class="n">get_pauli_expectation_value</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">xxy</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">backend</span><span class="o">.</span><span class="n">get_operator_expectation_value</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">op</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>-1.0
0.20000000000000068
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="asynchronous-job-submission">
<h3>Asynchronous Job Submission<a class="headerlink" href="#asynchronous-job-submission" title="Permalink to this headline"></a></h3>
<p>In the near future, as we look to more sophisticated algorithms and larger problem instances, the quantity and size of <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s to be run per experiment and the number of shots required to obtain satisfactory precision will mean the time taken for the quantum computation could exceed that of the classical computation. At this point, the overall algorithm can be sped up by maintaining maximum throughput on the quantum device and minimising how often the quantum device is left idle whilst the classical system is determining the next <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> s to send. This can be achieved by writing your algorithm to operate asynchronously.</p>
<p>The intended semantics of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> methods are designed to enable asynchronous execution of quantum programs whenever admissible from the underlying API provided by the device/simulator. <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.process_circuit&lt;s&gt;()</span></code> will submit the <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> (s) and immediately return.</p>
<p>The progress can be checked by querying <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.circuit_status()</span></code>. If this returns a <code class="xref py py-class docutils literal notranslate"><span class="pre">CircuitStatus</span></code> matching <code class="docutils literal notranslate"><span class="pre">StatusEnum.COMPLETED</span></code>, then <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.get_X()</span></code> will obtain the results and return immediately, otherwise it will block the thread and wait until the results are available.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.backends</span> <span class="kn">import</span> <span class="n">StatusEnum</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">IBMQBackend</span>
<span class="kn">from</span> <span class="nn">pytket.utils</span> <span class="kn">import</span> <span class="n">expectation_from_counts</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">IBMQBackend</span><span class="p">(</span><span class="s2">&quot;ibmq_quito&quot;</span><span class="p">)</span>

<span class="n">state</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">state</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># Compute expectation value for -0.3i ZZZ + 0.8 XZZ + 1.2 XXX</span>
<span class="n">zzz</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">zzz</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">xzz</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">xzz</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">xxx</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">xxx</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">circ_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="p">[</span><span class="n">zzz</span><span class="p">,</span> <span class="n">xzz</span><span class="p">,</span> <span class="n">xxx</span><span class="p">]:</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
    <span class="n">c</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
    <span class="n">circ_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">backend</span><span class="o">.</span><span class="n">get_compiled_circuit</span><span class="p">(</span><span class="n">c</span><span class="p">))</span>
<span class="n">coeff_list</span> <span class="o">=</span> <span class="p">[</span>
    <span class="o">-</span><span class="mf">0.3</span><span class="n">j</span><span class="p">,</span>  <span class="c1"># ZZZ</span>
    <span class="mf">0.8</span><span class="p">,</span>    <span class="c1"># XZZ</span>
    <span class="mf">1.2</span>     <span class="c1"># XXX</span>
<span class="p">]</span>

<span class="n">handle_list</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuits</span><span class="p">(</span><span class="n">circ_list</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">check_at_intervals</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="n">handle</span><span class="p">,</span> <span class="n">interval</span><span class="p">):</span>
    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">interval</span><span class="p">)</span>
        <span class="n">status</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">circuit_status</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">status</span><span class="o">.</span><span class="n">status</span> <span class="ow">in</span> <span class="p">(</span><span class="n">StatusEnum</span><span class="o">.</span><span class="n">COMPLETED</span><span class="p">,</span> <span class="n">StatusEnum</span><span class="o">.</span><span class="n">ERROR</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">status</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">expectation</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="n">handle</span><span class="p">,</span> <span class="n">coeff</span><span class="p">):</span>
    <span class="k">await</span> <span class="n">check_at_intervals</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="n">handle</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
    <span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">coeff</span> <span class="o">*</span> <span class="n">expectation_from_counts</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">task_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">expectation</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="n">h</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span> <span class="k">for</span> <span class="n">h</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">handle_list</span><span class="p">,</span> <span class="n">coeff_list</span><span class="p">)])</span>
    <span class="n">done</span><span class="p">,</span> <span class="n">pending</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">task_set</span><span class="p">,</span> <span class="n">return_when</span><span class="o">=</span><span class="n">asyncio</span><span class="o">.</span><span class="n">ALL_COMPLETED</span><span class="p">)</span>
    <span class="nb">sum</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">done</span><span class="p">:</span>
        <span class="nb">sum</span> <span class="o">+=</span> <span class="k">await</span> <span class="n">t</span>

    <span class="nb">print</span><span class="p">(</span><span class="nb">sum</span><span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>(1.2087999999999999-0.002400000000000002j)
</pre></div>
</div>
</div>
</div>
<p>In some cases you may want to end execution early, perhaps because it is taking too long or you already have all the data you need. You can use the <code class="xref py py-meth docutils literal notranslate"><span class="pre">Backend.cancel()</span></code> method to cancel the job for a given <code class="xref py py-class docutils literal notranslate"><span class="pre">ResultHandle</span></code>. This is recommended to help reduce load on the devices if you no longer need to run the submitted jobs.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Asynchronous submission is currently available with the <code class="xref py py-class docutils literal notranslate"><span class="pre">IBMQBackend</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">AQTBackend</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">HoneywellBackend</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">BraketBackend</span></code> and <code class="xref py py-class docutils literal notranslate"><span class="pre">AerBackend</span></code>. It will be extended to others in future updates.</p>
</div>
</div>
<div class="section" id="persistent-handles">
<h3>Persistent Handles<a class="headerlink" href="#persistent-handles" title="Permalink to this headline"></a></h3>
<p>Being able to split your processing into distinct procedures for <code class="xref py py-class docutils literal notranslate"><span class="pre">Circuit</span></code> generation and result interpretation can help improve throughput on the quantum device, but it can also provide a way to split the processing between different Python sessions. This may be desirable when the classical computation to interpret the results and determine the next experiment parameters is sufficiently intensive that we would prefer to perform it offline and only reserve a quantum device once we are ready to run more. Furthermore, resuming with previously-generated results could benefit repeatability of experiments and better error-safety since the logged results can be saved and reused.</p>
<p>Some <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s support persistent handles, in that the <code class="xref py py-class docutils literal notranslate"><span class="pre">ResultHandle</span></code> object can be stored and the associated results obtained from another instance of the same <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> in a different session. This is indicated by the boolean <code class="docutils literal notranslate"><span class="pre">persistent_handles</span></code> property of the <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code>. Use of persistent handles can greatly reduce the amount of logging you would need to do to take advantage of this workflow.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">IBMQBackend</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">IBMQBackend</span><span class="p">(</span><span class="s2">&quot;ibmq_quito&quot;</span><span class="p">)</span>

<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">X</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CZ</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>
<span class="n">circ</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_compiled_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">)</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="n">n_shots</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span>

<span class="c1"># assert backend.persistent_handles</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">handle</span><span class="p">))</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>(&#39;5e8f3dcbbb7d8500119cfbf6&#39;, 0)
{(0, 1, 1): 1000}
</pre></div>
</div>
</div>
</div>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytket.backends</span> <span class="kn">import</span> <span class="n">ResultHandle</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">IBMQBackend</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">IBMQBackend</span><span class="p">(</span><span class="s2">&quot;ibmq_quito&quot;</span><span class="p">)</span>

<span class="n">handle</span> <span class="o">=</span> <span class="n">ResultHandle</span><span class="o">.</span><span class="n">from_str</span><span class="p">(</span><span class="s2">&quot;(&#39;5e8f3dcbbb7d8500119cfbf6&#39;, 0)&quot;</span><span class="p">)</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span><span class="o">.</span><span class="n">get_counts</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">counts</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>{(0, 1, 1): 1000}
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="result-serialization">
<h3>Result Serialization<a class="headerlink" href="#result-serialization" title="Permalink to this headline"></a></h3>
<p>When performing experiments using <code class="xref py py-class docutils literal notranslate"><span class="pre">Backend</span></code> s, it is often useful to be able to easily store and retrieve the results for later analysis or backup.
This can be achieved using native serialiaztion and deserialization of <code class="xref py py-class docutils literal notranslate"><span class="pre">BackendResult</span></code> objects from JSON compatible dictionaries, using the <code class="xref py py-meth docutils literal notranslate"><span class="pre">to_dict()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">from_dict()</span></code> methods.</p>
<div class="jupyter_cell jupyter_container docutils container">
<div class="cell_input code_cell docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">pytket</span> <span class="kn">import</span> <span class="n">Circuit</span>
<span class="kn">from</span> <span class="nn">pytket.backends.backendresult</span> <span class="kn">import</span> <span class="n">BackendResult</span>
<span class="kn">from</span> <span class="nn">pytket.extensions.qiskit</span> <span class="kn">import</span> <span class="n">AerBackend</span>

<span class="n">circ</span> <span class="o">=</span> <span class="n">Circuit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">circ</span><span class="o">.</span><span class="n">H</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">CX</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">measure_all</span><span class="p">()</span>

<span class="n">backend</span> <span class="o">=</span> <span class="n">AerBackend</span><span class="p">()</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">process_circuit</span><span class="p">(</span><span class="n">circ</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">get_result</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>

<span class="k">with</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">TemporaryFile</span><span class="p">(</span><span class="s1">&#39;w+&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">fp</span><span class="p">:</span>
    <span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">res</span><span class="o">.</span><span class="n">to_dict</span><span class="p">(),</span> <span class="n">fp</span><span class="p">)</span>
    <span class="n">fp</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">new_res</span> <span class="o">=</span> <span class="n">BackendResult</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">fp</span><span class="p">))</span>

<span class="nb">print</span><span class="p">(</span><span class="n">new_res</span><span class="o">.</span><span class="n">get_counts</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-none notranslate"><div class="highlight"><pre><span></span>Counter({(0, 0): 7, (1, 1): 3})
</pre></div>
</div>
</div>
</div>
<dl class="citation">
<dt class="label" id="niel2001"><span class="brackets"><a class="fn-backref" href="#id1">Niel2001</a></span></dt>
<dd><p>Nielsen, M.A. and Chuang, I.L., 2001. Quantum computation and quantum information. Phys. Today, 54(2), p.60.</p>
</dd>
<dt class="label" id="wils2020"><span class="brackets"><a class="fn-backref" href="#id2">Wils2020</a></span></dt>
<dd><p>Wilson, E., Singh, S. and Mueller, F., 2020. Just-in-time Quantum Circuit Transpilation Reduces Noise. arXiv preprint arXiv:2005.12820.</p>
</dd>
</dl>
</div>
</div>
</div>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="manual_circuit.html" class="btn btn-neutral float-left" title="Circuit Construction" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="manual_compiler.html" class="btn btn-neutral float-right" title="Compilation" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2020-2021 Cambridge Quantum Computing Ltd.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>